package com.module.ble.widget

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.DashPathEffect
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Point
import android.graphics.RectF
import android.graphics.Shader
import android.graphics.Typeface
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.animation.DecelerateInterpolator
import com.common.base.app.extras.dp2px
import com.common.base.utils.ViewUtils.getColor
import com.module.ble.R
import com.module.ble.data.bean.CusChartData
import com.module.ble.utils.CommonCusHealthType
import java.util.Calendar
import kotlin.math.abs
import kotlin.math.roundToInt

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：2024/10/24
 *
 * 描述：周浮标图表
 *
 * 修订历史：
 *
 */
class FloatWeekChart(context: Context, attrs: AttributeSet?=null) : View(context, attrs) {

    private var businessType = CommonCusHealthType.BODYTEMP.value

    private var onDaySelectListener: ((time: Long, max: Float, min: Float) -> Unit)? = null
    private var onDayMoveListener: ((isPre: Boolean) -> Unit)? = null

    //屏幕宽高
    private var scrWidth = 0f
    private var scrHeight = 0f
    private val totalBarsPerWeek = 7 // 一周7天
    private var xData: Array<String> =
        arrayOf("周一", "周二", "周三", "周四", "周五", "周六", "周日")
    private var yData: Array<Int> = arrayOf(100, 90, 80, 70, 0)
    private var heartData = mutableListOf<CusChartData>()
    private lateinit var paintLine: Paint //y轴线
    private lateinit var zeroPaintLine: Paint //y轴0线
    private lateinit var paintGradientLine: Paint //指示渐变竖线
    private lateinit var paintXText: Paint //x轴坐标
    private lateinit var paintYText: Paint //y轴坐标
    private lateinit var paintRound: Paint  //指示滑块圆
    private lateinit var paintBessel: Paint  //滑块底部

    private var xSlider = 0f //滑块的x轴位置

    private var mPath: Path  //滑块贝塞尔

    //第一条曲线的坐标
    private val mFirstCurveStartPoint = Point()
    private val mFirstCurveEndPoint = Point()
    private val mFirstCurveControlPoint1 = Point()
    private val mFirstCurveControlPoint2 = Point()

    //第二条曲线的坐标
    private var mSecondCurveStartPoint = Point()
    private val mSecondCurveEndPoint = Point()
    private val mSecondCurveControlPoint1 = Point()
    private val mSecondCurveControlPoint2 = Point()

    private var isRest = false //是否静息

    private val margin = 20f //左右两边距离
    private var xWithStart = 0f //x轴的起始点
    private var xWithEnd = 0f  //x轴结束点
    private var ySpacing = 0f //高度分割份数后间距
    private var xSpacing = 0f //x轴柱子分割份数后间距
    private var xTextSpacing = 0f //x轴文字分割份数后间距

    // 缓存相关
    private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
    private var barGradientShader: Shader? = null

    // 控制变量
    private var showZeroLine = true
    private var showSlider = false

    private var paintBarDefaultColor = getColor(R.color.c_2a7fd8)
    private var paintBarSelectColor = getColor(R.color.c_2a7fd8)
    private var zeroLineColor= getColor(R.color.c_2a7fd8)    // 0刻度线线条颜色

    // 添加控制开关和最大值常量
    private var showBarBackground = false

    private var showYAxisLabel = true  // 控制是否显示右边文字
    private val textLineGap = dp2px(8f)  // 文字和虚线之间的间距
    private var maxYAxisTextWidth = 0f  // 缓存最大文字宽度

    private val barWidth = dp2px(6f) // 固定柱子宽度
    private val curveCircleRadius = barWidth / 2f // 圆点半径设为柱子宽度的一半

    init {
        setLayerType(LAYER_TYPE_SOFTWARE, null)
        isDrawingCacheEnabled = true
        setWillNotDraw(false)
        mPath = Path()
        initPaint()
    }

    private fun initPaint() {
        paintLine = Paint().apply {
            style = Paint.Style.STROKE
            strokeWidth = 1f
            color = getColor(R.color.c_2e2e2e)
            pathEffect = DashPathEffect(floatArrayOf(12f, 6f), 0f)
        }

        zeroPaintLine= Paint().apply {
            style = Paint.Style.STROKE
            strokeWidth = 1f
            color = zeroLineColor
            // 设置虚线效果
            // 第一个参数数组表示虚线的格式：[实线长度, 空白长度]
            pathEffect = DashPathEffect(floatArrayOf(12f, 6f), 0f)
        }

        paintGradientLine = Paint().apply {
            style = Paint.Style.STROKE
            strokeWidth = 2f
        }

        paintXText = Paint().apply {
            isAntiAlias = true
            strokeWidth = 1f
            textSize = dp2px(12f)
            textAlign = Paint.Align.CENTER
            color = getColor(R.color.black)
        }

        paintYText = Paint().apply {
            isAntiAlias = true
            textSize = dp2px(11f)
            strokeWidth = 1f
            textAlign = Paint.Align.RIGHT
            color = getColor(R.color.color_808080)
        }

        paintRound = Paint().apply {
            style = Paint.Style.FILL
            isAntiAlias = true
            color = getColor(R.color.c_5bfdb9)
        }

        paintBessel = Paint().apply {
            style = Paint.Style.FILL
            isAntiAlias = true
            color = getColor(R.color.color_eeeded)
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        scrWidth = width.toFloat()
        scrHeight = height.toFloat()

        ySpacing = height * 1.05f / 6f

        maxYAxisTextWidth = if (showYAxisLabel) {
            yData.maxOf { paintYText.measureText(it.toString()) }
        } else {
            0f
        }

        val firstTextWidth = paintXText.measureText(xData[0])

        xWithStart = margin + firstTextWidth / 2
        xWithEnd = scrWidth - margin - (if (showYAxisLabel) maxYAxisTextWidth + textLineGap else 0f)

        val totalWidth = xWithEnd - xWithStart

        // 修改间距计算，现在基于7天
        xTextSpacing = totalWidth / (xData.size - 1)
        xSpacing = totalWidth / (totalBarsPerWeek - 1)

        xSlider = xWithStart
    }

    private var mDownX = 0f
    private var mDownY = 0f
    private var isSlider = false //是否开启触摸模式

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (!showSlider) return false

        if (heartData.isNullOrEmpty()) return true//无数据是直接透传触摸

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                mDownX = event.x
                mDownY = event.y

                // 扩大滑块的触摸判定区域
                val bottomY = ySpacing * 5.3f
                val touchArea = RectF(
                    xSlider - curveCircleRadius * 3f,
                    bottomY - curveCircleRadius * 3f,
                    xSlider + curveCircleRadius * 3f,
                    bottomY + curveCircleRadius * 3f
                )
                isSlider = touchArea.contains(event.x, event.y)
                return true
            }

            MotionEvent.ACTION_MOVE -> {
                if (isSlider) {
                    // 限制滑动范围
                    xSlider = event.x.coerceIn(xWithStart, xWithEnd)
                    findAndNotifySelectedBar()
                    invalidate()
                    return true
                }
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                if (isSlider) {
                    // 吸附到最近的数据点
                    snapToNearestBar()
                } else {
                    // 处理点击事件
                    val dx = abs(event.x - mDownX)
                    val dy = abs(event.y - mDownY)

                    if (dx < touchSlop && dy < touchSlop) {
                        // 点击事件，直接跳转到点击位置
                        xSlider = event.x.coerceIn(xWithStart, xWithEnd)
                        snapToNearestBar()
                    } else if (dx > touchSlop) {
                        // 左右滑动切换日期
                        onDayMoveListener?.invoke(event.x > mDownX)
                    }
                }
                return true
            }
        }
        return super.onTouchEvent(event)
    }

    private fun findAndNotifySelectedBar() {
        // 调整索引计算，考虑周视图的间距
        val selectedIndex = ((xSlider - xWithStart) / xSpacing).roundToInt()
            .coerceIn(0, heartData.size - 1)

        if (selectedIndex in heartData.indices) {
            val data = heartData[selectedIndex]
            onDaySelectListener?.invoke(data.createdTime, data.mValue, data.minValue)
        }
    }


    private fun getBarXPosition(index: Int): Float {
        return xWithStart + (index * xSpacing)
    }

    private fun snapToNearestBar() {
        val selectedIndex = ((xSlider - xWithStart) / xSpacing).roundToInt()
            .coerceIn(0, heartData.size - 1)

        var nearestIndex = selectedIndex
        var minDistance = Int.MAX_VALUE
        val searchRange = 0  // 可以适当调整搜索范围

        for (i in maxOf(0, selectedIndex - searchRange)..minOf(
            heartData.size - 1,
            selectedIndex + searchRange
        )) {
            if (heartData[i].mValue > 0) {
                val distance = abs(i - selectedIndex)
                if (distance < minDistance) {
                    minDistance = distance
                    nearestIndex = i
                }
            }
        }

        xSlider = getBarXPosition(nearestIndex)

        onDaySelectListener?.invoke(
            heartData[nearestIndex].createdTime,
            heartData[nearestIndex].mValue, heartData[nearestIndex].minValue
        )


        invalidate()
    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        canvas.save()
        canvas.clipRect(0f, 0f, scrWidth, scrHeight)

        drawY(canvas)
        if (showSlider) drawGradientLine(canvas)
        drawPillar(canvas)
        if (showSlider) drawBessel(canvas)
        drawX(canvas)

        canvas.restore()
    }


    // 精确计算Y轴位置
    fun calculateYPosition(value: Int): Float {

        val yStart = ySpacing  // 对应最高刻度位置
        val section1 = ySpacing * 2
        val section2 = ySpacing * 3
        val section3 = ySpacing * 4
        val yEnd = ySpacing * 5      // 对应0刻度位置

        return when (businessType) {
            CommonCusHealthType.HEARTRATE.value -> {
                // 200-0的刻度逻辑
                when {
                    value >= 150 -> {
                        // 150-200区间
                        val ratio = (value - 150) / 50f
                        yStart + (section1 - yStart) * (1 - ratio)
                    }

                    value >= 100 -> {
                        // 100-150区间
                        val ratio = (value - 100) / 50f
                        section1 + (section2 - section1) * (1 - ratio)
                    }

                    value >= 50 -> {
                        // 50-100区间
                        val ratio = (value - 50) / 50f
                        section2 + (section3 - section2) * (1 - ratio)
                    }

                    value > 0 -> {
                        // 0-50区间
                        val ratio = value / 50f
                        section3 + (yEnd - section3) * (1 - ratio)
                    }

                    else -> yEnd
                }
            }
            CommonCusHealthType.BODYTEMP.value -> {
                when {
                    value >= 38 -> {
                        // 38-42区间 (4刻度)
                        val ratio = (value - 38) / 4f
                        yStart + (section1 - yStart) * (1 - ratio)
                    }

                    value >= 34 -> {
                        // 34-38区间 (4刻度)
                        val ratio = (value - 34) / 4f
                        section1 + (section2 - section1) * (1 - ratio)
                    }

                    value >= 30 -> {
                        // 30-34区间 (4刻度)
                        val ratio = (value - 30) / 4f
                        section2 + (section3 - section2) * (1 - ratio)
                    }

                    value >= 26 -> {
                        // 26-30区间 (4刻度)
                        val ratio = (value - 26) / 4f
                        section3 + (yEnd - section3) * (1 - ratio)
                    }

                    else -> yEnd  // 小于26的值都显示在最底部
                }
            }

            else -> {
                // 原有的100-0的刻度逻辑
                when {
                    value >= 90 -> {
                        // 90-100区间
                        val ratio = (value - 90) / 10f
                        yStart + (section1 - yStart) * (1 - ratio)
                    }

                    value >= 80 -> {
                        // 80-90区间
                        val ratio = (value - 80) / 10f
                        section1 + (section2 - section1) * (1 - ratio)
                    }

                    value >= 70 -> {
                        // 70-80区间
                        val ratio = (value - 70) / 10f
                        section2 + (section3 - section2) * (1 - ratio)
                    }

                    value > 0 -> {
                        // 0-70区间
                        val ratio = value / 70f
                        section3 + (yEnd - section3) * (1 - ratio)
                    }

                    else -> yEnd
                }
            }
        }
    }

    private fun drawPillar(canvas: Canvas) {
        heartData.forEachIndexed { index, data ->
            val x = getBarXPosition(index)
            val barStartX = x - barWidth / 2
            val barEndX = x + barWidth / 2
            val barCenterX = x

            if (data.mValue > 0) {
                val isSelected = showSlider && abs(barCenterX - xSlider) < xSpacing / 4

                val topY = calculateYPosition(data.mValue.toInt())
                val bottomY = calculateYPosition(data.minValue.toInt())

                // 调试日志
                Log.d("FloatWeekChart", "Value: ${data.mValue}, Y: $topY")
                Log.d("FloatWeekChart", "MinValue: ${data.minValue}, Y: $bottomY")

                if (businessType == CommonCusHealthType.BODYTEMP.value) {
                    // 确保所有值都在26-42的范围内
                        if (data.mValue - data.minValue <= 0) {
                            // 计算中心点
                            val centerY = (topY + bottomY) / 2

                            // 使用valueDifference作为柱子高度
                            val barHeight = 1f
                            val cornerRadius = barHeight / 2 // 圆角半径为高度的一半

                            // 根据固定高度计算实际的顶部和底部位置
                            val adjustedTopY = centerY - barHeight / 2
                            val adjustedBottomY = centerY + barHeight / 2

                            // 创建圆角矩形路径
                            val barPath = Path().apply {
                                addRoundRect(
                                    RectF(
                                        barStartX,
                                        adjustedTopY,
                                        barEndX,
                                        adjustedBottomY
                                    ),
                                    cornerRadius,
                                    cornerRadius,
                                    Path.Direction.CW
                                )
                            }

                            // 绘制柱子
                            val barPaint = Paint().apply {
                                style = Paint.Style.FILL
                                isAntiAlias = true
                                color = if (isSelected) paintBarSelectColor else paintBarDefaultColor
                            }
                            canvas.drawPath(barPath, barPaint)

//                            // 如果未选中，添加渐变效果
//                            if (!isSelected) {
//                                val gradientPaint = Paint().apply {
//                                    shader = LinearGradient(
//                                        barStartX, adjustedTopY,
//                                        barStartX, adjustedBottomY,
//                                        intArrayOf(
//                                            getColor(R.color.c_4b94f0),
//                                            getColor(R.color.transparent)
//                                        ),
//                                        null,
//                                        Shader.TileMode.CLAMP
//                                    )
//                                    isAntiAlias = true
//                                }
//                                canvas.drawPath(barPath, gradientPaint)
//                            }
                        }else{
                            // 绘制柱子
                            val barHeight = abs(bottomY - topY)  // 使用实际计算出的高度
                            val cornerRadius = barHeight / 2     // 圆角半径为高度的一半

                            // 创建圆角矩形路径
                            val barPath = Path().apply {
                                addRoundRect(
                                    RectF(
                                        barStartX,
                                        topY,           // 使用实际计算的顶部位置
                                        barEndX,
                                        bottomY         // 使用实际计算的底部位置
                                    ),
                                    cornerRadius,
                                    cornerRadius,
                                    Path.Direction.CW
                                )
                            }

                            // 绘制柱子
                            val barPaint = Paint().apply {
                                style = Paint.Style.FILL
                                isAntiAlias = true
                                color = if (isSelected) paintBarSelectColor else paintBarDefaultColor
                            }
                            canvas.drawPath(barPath, barPaint)

//                            // 如果未选中，添加渐变效果
//                            if (!isSelected) {
//                                val gradientPaint = Paint().apply {
//                                    shader = LinearGradient(
//                                        barStartX, topY,
//                                        barStartX, bottomY,
//                                        intArrayOf(
//                                            getColor(R.color.c_4b94f0),
//                                            getColor(R.color.transparent)
//                                        ),
//                                        null,
//                                        Shader.TileMode.CLAMP
//                                    )
//                                    isAntiAlias = true
//                                }
//                                canvas.drawPath(barPath, gradientPaint)
//                            }
                        }
                } else {
                    val valueDifference = if (data.mValue - data.minValue <= 1) 2 else data.mValue - data.minValue
                    if (valueDifference.toFloat() <= 10) {
                        val centerY = (topY + bottomY) / 2  // 计算中心点
                        val barHeight = valueDifference.toFloat()  // 柱子高度等于差值
                        val cornerRadius = barHeight / 2  // 圆角半径为差值的一半

                        // 计算柱子的顶部和底部位置
                        val adjustedTopY = centerY - barHeight / 2
                        val adjustedBottomY = centerY + barHeight / 2

                        // 创建圆角矩形路径
                        val barPath = Path().apply {
                            addRoundRect(
                                RectF(
                                    barStartX,
                                    adjustedTopY,
                                    barEndX,
                                    adjustedBottomY
                                ),
                                cornerRadius, // x方向圆角半径
                                cornerRadius, // y方向圆角半径
                                Path.Direction.CW
                            )
                        }

                        // 绘制柱子
                        val barPaint = Paint().apply {
                            style = Paint.Style.FILL
                            isAntiAlias = true
                            color = if (isSelected) paintBarSelectColor else paintBarDefaultColor
                        }
                        canvas.drawPath(barPath, barPaint)

                        // 如果未选中，添加渐变效果
//                        if (!isSelected) {
//                            val gradientPaint = Paint().apply {
//                                shader = LinearGradient(
//                                    barStartX, adjustedTopY,
//                                    barStartX, adjustedBottomY,
//                                    intArrayOf(
//                                        getColor(R.color.c_4b94f0),
//                                        getColor(R.color.transparent)
//                                    ),
//                                    null,
//                                    Shader.TileMode.CLAMP
//                                )
//                                isAntiAlias = true
//                            }
//                            canvas.drawPath(barPath, gradientPaint)
//                        }
                    } else {
                        // 绘制柱状图
                        val barPath = Path().apply {
                            // 顶部圆弧
                            addArc(
                                RectF(barStartX, topY, barEndX, topY + barWidth),
                                180f, 180f
                            )
                            // 矩形主体
                            addRect(
                                RectF(
                                    barStartX,
                                    topY + barWidth / 2,
                                    barEndX,
                                    bottomY - barWidth / 2
                                ),
                                Path.Direction.CW
                            )
                            // 底部圆弧
                            addArc(
                                RectF(barStartX, bottomY - barWidth, barEndX, bottomY),
                                0f, 180f
                            )
                        }

                        val barPaint = Paint().apply {
                            style = Paint.Style.FILL
                            isAntiAlias = true
                            color = if (isSelected) paintBarSelectColor else paintBarDefaultColor
                        }
                        canvas.drawPath(barPath, barPaint)

//                        if (!isSelected) {
//                            val gradientPaint = Paint().apply {
//                                shader = LinearGradient(
//                                    0f, topY, 0f, bottomY,
//                                    intArrayOf(
//                                        getColor(R.color.c_4b94f0),
//                                        getColor(R.color.transparent)
//                                    ),
//                                    null,
//                                    Shader.TileMode.CLAMP
//                                )
//                                isAntiAlias = true
//                            }
//                            canvas.drawPath(barPath, gradientPaint)
//                        }
                    }
                }
            }
        }
    }

    private fun drawX(canvas: Canvas) {
        xData.forEachIndexed { index, s ->
            val x = xWithStart + xTextSpacing * index

            if (showSlider) {
                val dis = abs(x - xSlider)
                val besselTopY = ySpacing * 5.3f - curveCircleRadius * 1.7f
                var y = besselTopY + paintXText.textSize / 2

                if (dis < xTextSpacing / 2) {
                    paintXText.typeface = Typeface.DEFAULT_BOLD
                    val liftRatio = (1 - dis / (xTextSpacing / 2)).coerceIn(0f, 1f)
                    val liftDistance = 32f
                    y -= liftDistance * liftRatio
                } else {
                    paintXText.typeface = Typeface.DEFAULT
                }

                canvas.drawText(s, x, y, paintXText)
            } else {
                paintXText.typeface = Typeface.DEFAULT
                val y = height - dp2px(10f)
                canvas.drawText(s, x, y, paintXText)
            }
        }
    }

    private fun drawY(canvas: Canvas) {
        // 先绘制刻度线，不受 showYAxisLabel 影响
        for (i in 0..4) {
            val lineY = ySpacing * (i + 1)

            if (i == 4 && !showZeroLine) continue
            val paint = if (i == 4) zeroPaintLine else paintLine // i == 4 时是0刻度线
            canvas.drawLine(
                xWithStart,
                lineY,
                xWithEnd,
                lineY,
                paint
            )
        }

        // 只有在 showYAxisLabel 为 true 时才绘制文字
        if (!showYAxisLabel) return

        val textHeight = paintYText.fontMetrics.let { it.descent - it.ascent }

        for (i in 0..4) {
            val lineY = ySpacing * (i + 1)

            if (i == 4 && !showZeroLine) continue

            val text = yData[i].toString()
            val textWidth = paintYText.measureText(text)
            val textX = scrWidth - margin - (maxYAxisTextWidth - textWidth) / 2

            canvas.drawText(
                text,
                textX,
                lineY + (textHeight / 2) - paintYText.fontMetrics.descent,
                paintYText
            )
        }
    }

    private fun drawGradientLine(canvas: Canvas) {
        if (!showSlider) return

        val startY = ySpacing
        val endY = ySpacing * 4.8f

        val gradient = LinearGradient(
            xSlider, startY, xSlider, endY,
            intArrayOf(
                getColor(R.color.transparent),
                zeroLineColor,
                getColor(R.color.transparent)
            ), null, Shader.TileMode.MIRROR
        )
        paintGradientLine.shader = gradient

        canvas.drawLine(xSlider, startY, xSlider, endY, paintGradientLine)
    }

    private fun drawBessel(canvas: Canvas) {
        // 如果不显示滑块，直接返回
        if (!showSlider) return

        //系数值增大滑块位置下移,减小则会使滑块位置上移
        val bottomY = ySpacing * 5.4f

        // 微调贝塞尔曲线参数
        val blueCircleRadius = 12f * 1.8f
        // 减小曲线凸起高度，使文字更贴近
        val curveHeight = blueCircleRadius * 0.5f
        val curveWidth = blueCircleRadius * 3.8f

        // 调整圆点位置，减小乘数使圆点位置略微上移(直接减小circleY的值来使圆点上移10px)
        val circleY = bottomY + blueCircleRadius * 0.4f - 10f

        // 第一条曲线的起始点和控制点设置
        mFirstCurveStartPoint[(xSlider - curveWidth).toInt()] = bottomY.toInt()
        mFirstCurveEndPoint[xSlider.toInt()] = (circleY - blueCircleRadius - curveHeight).toInt()
        mSecondCurveStartPoint = mFirstCurveEndPoint
        mSecondCurveEndPoint[(xSlider + curveWidth).toInt()] = bottomY.toInt()

        // 控制点调整，使曲线更平滑
        mFirstCurveControlPoint1[(mFirstCurveStartPoint.x + curveWidth * 0.4f).toInt()] =
            mFirstCurveStartPoint.y
        mFirstCurveControlPoint2[(mFirstCurveEndPoint.x - curveWidth * 0.4f).toInt()] =
            mFirstCurveEndPoint.y

        mSecondCurveControlPoint1[(mSecondCurveStartPoint.x + curveWidth * 0.4f).toInt()] =
            mSecondCurveStartPoint.y
        mSecondCurveControlPoint2[(mSecondCurveEndPoint.x - curveWidth * 0.4f).toInt()] =
            mSecondCurveEndPoint.y

        // 绘制贝塞尔曲线路径
        mPath.reset()
        mPath.moveTo(0f, bottomY)
        mPath.lineTo(mFirstCurveStartPoint.x.toFloat(), mFirstCurveStartPoint.y.toFloat())
        mPath.cubicTo(
            mFirstCurveControlPoint1.x.toFloat(), mFirstCurveControlPoint1.y.toFloat(),
            mFirstCurveControlPoint2.x.toFloat(), mFirstCurveControlPoint2.y.toFloat(),
            mFirstCurveEndPoint.x.toFloat(), mFirstCurveEndPoint.y.toFloat()
        )
        mPath.cubicTo(
            mSecondCurveControlPoint1.x.toFloat(), mSecondCurveControlPoint1.y.toFloat(),
            mSecondCurveControlPoint2.x.toFloat(), mSecondCurveControlPoint2.y.toFloat(),
            mSecondCurveEndPoint.x.toFloat(), mSecondCurveEndPoint.y.toFloat()
        )
        mPath.lineTo(scrWidth, bottomY)
        mPath.lineTo(scrWidth, scrHeight)
        mPath.lineTo(0f, scrHeight)
        mPath.close()

        // 绘制路径和圆点
        canvas.drawPath(mPath, paintBessel)
        canvas.drawCircle(xSlider, circleY, blueCircleRadius, paintRound)
    }

    fun setValue(
        value: List<CusChartData>, resetPosition: Boolean = true,
        defaultPosition: Int = -1,  // -1表示自动查找第一个有效值，否则使用指定位置
    ): FloatWeekChart {
        heartData.clear()
        heartData = value.take(totalBarsPerWeek).toMutableList()

        if (resetPosition) {
            barGradientShader = null
            invalidate()

            // 在绘制完成后设置默认位置
            post {
                // 确定默认位置
                val targetPosition = when (defaultPosition) {
                    in 0 until heartData.size -> defaultPosition
                    else -> heartData.indexOfFirst { it.mValue > 0 }.takeIf { it != -1 } ?: 0
                }

                // 设置滑块位置
                xSlider = getBarXPosition(targetPosition)

                // 通知选中的数据
                val data = heartData[targetPosition]
                if (data.mValue > 0) {
                    onDaySelectListener?.invoke(data.createdTime, data.mValue, data.minValue)
                }

                invalidate()
            }
        } else {
            barGradientShader = null
            invalidate()
        }

        return this
    }

    // 添加动画效果
    private fun animateSliderTo(targetX: Float) {
        ValueAnimator.ofFloat(xSlider, targetX).apply {
            duration = 300
            interpolator = DecelerateInterpolator()
            addUpdateListener { animator ->
                xSlider = animator.animatedValue as Float
                invalidate()
            }
            start()
        }
    }

    // 添加一个辅助方法，用于根据时间戳查找对应的位置
    fun findPositionByTime(targetTime: Long): Int {
        // 将目标时间转换为当天00:00:00
        val calendar = Calendar.getInstance().apply {
            timeInMillis = targetTime
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }
        val targetDayStart = calendar.timeInMillis

        // 查找匹配的数据位置
        return heartData.indexOfFirst { data ->
            val dataCalendar = Calendar.getInstance().apply {
                timeInMillis = data.createdTime
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }
            dataCalendar.timeInMillis == targetDayStart
        }.takeIf { it != -1 } ?: 0
    }

    fun setOnDaySelectListener(l: ((time: Long, max: Float, min: Float) -> Unit)): FloatWeekChart {
        this.onDaySelectListener = l
        return this
    }

    fun setRest(isRest: Boolean) {
        this.isRest = isRest
        postInvalidate()
    }

    fun setShowZeroLine(show: Boolean): FloatWeekChart {
        this.showZeroLine = show
        postInvalidate()
        return this
    }

    fun setShowZeroLineColor(mColor: Int): FloatWeekChart {
        this.zeroLineColor = mColor
        this.zeroPaintLine.color = zeroLineColor
        this.paintRound.color = zeroLineColor
        invalidate()
        return this
    }

    fun setBarColor(defaultColor: Int,selectColor: Int): FloatWeekChart {
        this.paintBarDefaultColor = defaultColor
        this.paintBarSelectColor = selectColor
        invalidate()
        return this
    }

    /**
     * 设置是否显示底部滑块
     * @param show Boolean true显示滑块和指示器，false只显示时间文字
     */
    fun setShowSlider(show: Boolean): FloatWeekChart {
        this.showSlider = show
        invalidate()
        return this
    }

    // 添加设置方法
    fun setShowBarBackground(show: Boolean): FloatWeekChart {
        this.showBarBackground = show
        postInvalidate()
        return this
    }

    fun setShowYAxisLabel(show: Boolean): FloatWeekChart {
        this.showYAxisLabel = show
        postInvalidate()  // 需要重新布局因为会影响图表宽度
        return this
    }

    // 可以添加一个方法来设置自定义的X轴标签
    fun setXAxisLabels(labels: Array<String>) {
        if (labels.size == totalBarsPerWeek) {
            xData = labels
            invalidate()
        }
    }

    fun setBusinessType(type: Int): FloatWeekChart {
        businessType = type
        // 根据业务类型设置对应的刻度值
        yData = when (type) {
            CommonCusHealthType.HEARTRATE.value -> {
                arrayOf(200, 150, 100, 50, 0)
            }
            CommonCusHealthType.BODYTEMP.value -> {
                arrayOf(42, 38, 34, 30, 26)
            }
            else -> {
                arrayOf(100, 90, 80, 70, 0)
            }
        }
        invalidate()
        return this
    }
}